<template>
  <el-dialog
    v-model="show"
    title="表字段编辑"
    width="600"
    destroy-on-close
    align-center
    draggable
    :before-close="handleDialogClose"
  >
    <el-form
      ref="itemFormRef"
      label-width="auto"
      label-position="right"
      :model="info"
      :rules="rules"
      @keyup.enter="keyUp"
    >
      <el-row :gutter="20" align="bottom">
        <el-col :span="14">
          <el-space fill>
            <el-alert type="info" show-icon :closable="false">
              <p>
                填数据表字段名，如：tbk_username，不能有中文；建议用 'tbk_'
                开头，长度控制在20个字符
              </p>
            </el-alert>
            <el-form-item label="字段名称" prop="name">
              <el-input
                v-model="info.name"
                maxlength="20"
                placeholder="tbl_user_info"
                show-word-limit
                type="text"
              />
            </el-form-item>
          </el-space>
        </el-col>
        <el-col :span="10">
          <el-space fill>
            <el-alert type="info" show-icon :closable="false">
              <p>选填字段存储数据类型，类型参照proto3的基础字段类型</p>
            </el-alert>
            <el-form-item label="数据类型" prop="type">
              <el-select v-model="info.type" clearable placeholder="默认String">
                <el-option
                  v-for="item in options"
                  :key="item.value"
                  :label="item.label"
                  :value="item.value"
                />
              </el-select>
            </el-form-item>
          </el-space>
        </el-col>
      </el-row>
      <el-space fill>
        <el-alert type="info" show-icon :closable="false">
          <p>
            字段是否创建索引以助查询；唯一索引可填索引名，建议 'udx_'
            开头。和其它字段的唯一索引名一样的，判断为联合索引
          </p>
        </el-alert>
        <el-form-item label="是否创建索引" prop="isIndex">
          <el-switch v-model="info.isIndex" />
          <span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>
          <transition name="el-zoom-in-top">
            <el-radio-group v-show="info.isIndex" v-model="info.index">
              <el-radio value="Hash">普通</el-radio>
              <el-radio value="Only">唯一</el-radio>
            </el-radio-group>
          </transition>
          <span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>
          <transition name="el-zoom-in-top">
            <el-input
              v-show="info.isIndex && info.index === 'Only'"
              v-model="info.unique"
              maxlength="15"
              placeholder="udx_username"
              show-word-limit
              type="text"
              style="width: 233px"
            />
          </transition>
        </el-form-item>
      </el-space>
      <el-space fill>
        <el-alert type="info" show-icon :closable="false">
          <p>
            字段备注信息，填字段的中文名，如果字段值是枚举值，还要填写枚举字典
          </p>
        </el-alert>
        <el-form-item label="信息备注" prop="memo">
          <el-input
            v-model="info.memo"
            maxlength="500"
            placeholder="用户姓名"
            show-word-limit
            type="textarea"
          />
        </el-form-item>
      </el-space>
    </el-form>
    <template #footer>
      <div class="dialog-footer">
        <el-button @click="cancel">取消</el-button>
        <el-button type="primary" @click="commit(itemFormRef)">
          确认
        </el-button>
      </div>
    </template>
  </el-dialog>
</template>

<script lang="ts" setup>
import { ref, reactive, watch, PropType, toRef } from "vue";
import { ErCol } from "@/components/x6antv";
import { ElMessageBox } from "element-plus";
import type { FormInstance, FormRules } from "element-plus";

const props = defineProps({
    show: {
      type: Boolean,
      default: false,
    },
    info: {
      type: Object as PropType<ErCol>,
      default: () => ({}),
    },
    items: {
      type: Array as PropType<ErCol[]>,
      default: () => [],
    },
  }),
  itemFormRef = ref<FormInstance>(),
  emit = defineEmits(["update:show", "commit"]),
  show = toRef(props.show),
  info = toRef(props.info),
  options = [
    {
      value: "String",
      label: "String",
    },
    {
      value: "Int32",
      label: "Int32",
    },
    {
      value: "Int64",
      label: "Int64",
    },
    {
      value: "Float",
      label: "Float",
    },
    {
      value: "Time",
      label: "Time",
    },
    {
      value: "Bytes",
      label: "Bytes",
    },
  ],
  validateName = (rule: any, value: any, callback: any) => {
    if (value != "") {
      if (props.items)
        for (let i = 0; i < props.items.length; i++) {
          const e = props.items[i];
          if (info.value.id && e.id === info.value.id) continue;
          if (e.name == value) {
            callback(new Error("该字段名称已存在"));
            return;
          }
        }
      callback();
    }
  },
  rules = reactive<FormRules<ErCol>>({
    name: [
      {
        required: true,
        message: "字段名不能为空",
        trigger: "blur",
      },
      {
        min: 2,
        max: 20,
        message: "字段长度控制在2到20个字符",
        trigger: "blur",
      },
      { validator: validateName, trigger: "blur" },
    ],
    memo: [
      {
        required: true,
        message: "字段备注不能为空",
        trigger: "blur",
      },
      {
        max: 500,
        message: "备注信息不能超过500个字符",
        trigger: "blur",
      },
    ],
  }),
  keyUp = (e: any) => {
    if (e.ctrlKey && e.keyCode == 13) {
      commit(itemFormRef.value);
    }
  },
  cancel = () => {
    show.value = false;
    emit("update:show", show.value);
  },
  commit = async (formEl: FormInstance | undefined) => {
    if (!formEl) return;
    await formEl.validate((valid, fields) => {
      if (valid) {
        if (!info.value.type) info.value.type = "String";
        if (info.value.isIndex && info.value.index === "Hash") {
          info.value.unique = "";
        }
        emit("commit", info.value);
        show.value = false;
        emit("update:show", show.value);
        console.log(show.value);
      }
    });
  },
  handleDialogClose = () => {
    ElMessageBox.confirm("你确定关闭对话框么?")
      .then(() => {
        cancel();
      })
      .catch(() => {
        // catch error
      });
  };

watch(
  () => props.show,
  (newVal, oldVal) => {
    show.value = newVal;
    if (newVal === true) {
      info.value = toRef(props.info).value;
    }
  }
);
</script>
